//
//  DateKLineData.cpp
//  Chart
//
//  Created by CaoJun on 13-9-5.
//
//

#include "DateKLineData.h"
#include <cmath>

using namespace ytx;
using namespace std;

KLineDataHandlerOfDayKLineData::KLineDataHandlerOfDayKLineData(DateKLineData & kLineData) : kLineData(kLineData)
{
    
}

void KLineDataHandlerOfDayKLineData::handle(ytx::KLineData *dayK, string eventName, void *data)
{
    if (dayK->getId() != kLineData.getId()) {
        return;
    }
    
    if(eventName == "kLineData.update"){
        kLineData.getCloseNewK();
        kLineData.checkNeedGetNewK();
    }
}

DateKLineData :: DateKLineData(string id, string currentDate, LineType::LineType quotationType, string marketType, int toFix, string name, string nickName, bool hasVolume, int limit, int threshold, int buffer, YTXTime tradedate, TimeKLineData * dayk) : KLineData(id, currentDate, quotationType, marketType, toFix, name, nickName, hasVolume, limit, threshold, buffer, tradedate), dayK(dayk), dataHandler(KLineDataHandlerOfDayKLineData(*this))
{
    
}


void DateKLineData::intervalRequestDataInterface()
{
    if(!dayK->hasData())
    {
        dayK->getK();
    }
    dayK->intervalRequestDataInterface();
}


void DateKLineData::listenOn()
{
    listenOff();
    if (dayK){
        dayK->on("kLineData.update", &dataHandler);
    }
    
}

void DateKLineData::listenOff()
{
    if (dayK){
        dayK->off("kLineData.update", &dataHandler);
    }
}

bool DateKLineData::isInLatestNewK(YTXTime tradedate1, YTXTime tradedate2){
    if (quotationType == LineType::L1d) {
        return tradedate2 >= tradedate1 + days(1);
    }
    else if (quotationType == LineType::L1w) {
        YTXTimeDuration dateDiff = tradedate2.date() - tradedate1.date();
        return  LineType::getRequestParamOfQuotationType(quotationType) >= dateDiff.getDiffDay();
    }
//    else if(quotationType == LineType::L1M){
//        YTXTimeDate newMonth = (tradedate1.date().end_of_month() + days(1)).end_of_month() + days(1);
//        return  newMonth >= tradedate2.date();
//    }
    return false;
}

bool DateKLineData::checkNeedGetNewK(){
    if ( !dayK->hasData() || !dayK->avgData->hasData()) {
        return false;
    }
    //如果分时的日期 不和数据的 最后一条 在同一个月或 同一周 则 取新数据
    
    if (!hasDataWithoutClose()) {
        return false;
    }
    
    YTXTime avgTime = YTXTime(Tools::parseLong(dayK->avgData->getUpdateTime()));
    YTXTime dateKTime = getTradedate();
//    MyPrintBase("dateKTime", Tools::ptime2StringYYYYMMddHHmmss(dateKTime));
//    MyPrintBase("avgTime", Tools::ptime2StringYYYYMMddHHmmss(avgTime));
    if (quotationType == LineType::L1w) {
        YTXTimeDuration dateDiff = avgTime.date() - dateKTime.date();
        if( LineType::getRequestParamOfQuotationType(quotationType) < dateDiff.getDiffDay()){
            getCloseNewK();
            return true;
        }
    }
//    else if(quotationType == LineType::L1M){
//        YTXTimeDate newMonth = (dateKTime.date().end_of_month() + days(1)).end_of_month() + days(1);
//        if(avgTime.date() > newMonth){
//            getCloseNewK();
//            return true;
//        }
//    }
    
    
    return false;
}

void DateKLineData::getCloseNewK()
{
    if(!dayK->hasData()){
        return;
    }
    
    YTXTime now = dayK->kLineData.back().dateTime; //: boost::posix_time::second_clock::local_time();
    YTXTimeDuration openTime = YTXTime(0);
    
    KLineItem result = quotationType == LineType::L1w ? dayK->getOCHLByWeek(now, openTime) : dayK->getOCHLByMonth(now, openTime);
    result.IsCurrent = 1;
    string date;   
    
    if(!std::isnan(result.open)){
        date = result.dateTime.toStringYYYYMMddHHmmss();
        
        vector<KLineItem> datas;
        
        vector<string> dates;
        datas.push_back(result);
        dates.push_back(date);
        
        bool isCalculate = concatCloseNewData(datas, dates);
        
//        if(kLineData.back().dateTime == result.dateTime){
//            closeDataFlag = true;
//        }
        
        if(isCalculate){
            calculateK();
        }
    }
}


void DateKLineData::getK()
{
    KLineData::getK();
    if (!dayK->hasDataWithoutClose()) {
        dayK->getK();
    }
}

void DateKLineData::calculateTodayKLine()
{
    getCloseNewK();
}

//周月K向未来去数据会有不正确数据
unsigned int DateKLineData::filterDataTo(vector<KLineItem> & data, vector<string> & dates)
{
    if (data.size() == 0 || !hasData()) {
        return 0;
    }
    YTXTime currentDate = kLineData.back().dateTime;
    YTXTime firstDate = data.back().dateTime;
    if (quotationType == LineType::L1w) {
        //在同一周
        if (currentDate.start_of_week_since_monday().date() == firstDate.start_of_week_since_monday().date()) {
            data.pop_back();
            dates.pop_back();
        }
    }
//    else if (quotationType == LineType::L1M) {
//        //在同一月
//        if (currentDate.start_of_month().date() == firstDate.start_of_month().date()) {
//            data.pop_back();
//            dates.pop_back();
//        }
//    }
    
    return (unsigned int)data.size();
}

unsigned int DateKLineData::filterDataFrom(vector<KLineItem> & data, vector<string> & dates)
{
    if (data.size() == 0 || !hasData()) {
        return 0;
    }
//    YTXTime currentDate = kLineData.front().dateTime;
//    YTXTime firstDate = data.back().dateTime;
//    if (quotationType == LineType::L1w) {
//        //在同一周
//        if (currentDate.start_of_week_since_monday().date() == firstDate.start_of_week_since_monday().date()) {
//            data.pop_back();
//            dates.pop_back();
//        }
//    }
//    else if (quotationType == LineType::L1M) {
//        //在同一月
//        if (currentDate.start_of_month().date() == firstDate.start_of_month().date()) {
//            data.pop_back();
//            dates.pop_back();
//        }
//    }
    return (unsigned int)data.size();
}
